package com.sys.config;

import com.sys.entity.SysUser;
import com.sys.mapper.SysUserMapper;
import com.sys.utils.JwtTokenUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * JWT 认证拦截器
 * 
 * 功能说明：
 * 1. 拦截所有HTTP请求（除了配置的公开路径）
 * 2. 从请求头中提取JWT Token
 * 3. 验证Token的有效性（签名、过期时间）
 * 4. 解析Token获取用户信息
 * 5. 将用户信息存入请求属性，供后续Controller使用
 * 
 * 工作流程：
 * 请求 -> 拦截器 -> 验证Token -> 放行/拒绝 -> Controller
 * 
 * 使用方式：
 * 前端需在请求头中携带Token：
 * headers: { 'token': 'eyJhbGciOiJIUzUxMiJ9...' }
 * 
 * @author Autism Intervention Team
 * @version 1.0
 */
@Component
public class JwtAuthenticationInterceptor implements HandlerInterceptor {

    /**
     * JWT工具类，用于解析和验证Token
     */
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    /**
     * 用户Mapper，用于查询用户信息
     */
    @Autowired
    private SysUserMapper userMapper;
    
    /**
     * 日志记录器
     */
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory
            .getLogger(JwtAuthenticationInterceptor.class);

    /**
     * 前置处理方法（在Controller方法执行前调用）
     * 
     * 主要职责：
     * 1. 提取并验证JWT Token
     * 2. 解析用户信息并存入请求属性
     * 3. 决定是否放行请求
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @param handler 处理器（Controller方法）
     * @return true-放行请求，false-拦截请求
     * @throws Exception 异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 判断当前拦截到的是否是Controller的方法
        if (!(handler instanceof org.springframework.web.method.HandlerMethod)) {
            // 不是Controller方法（如静态资源），直接放行
            return true;
        }

        // 2. 从请求头中获取JWT Token
        // 前端需在请求头中设置：headers: { 'token': 'xxx' }
        String token = request.getHeader("token");

        // 3. 校验Token并解析用户信息
        try {
            log.info("开始JWT校验，Token: {}", token);
            
            // 解析JWT Token，获取载荷（Payload）
            Claims claims = jwtTokenUtil.parseJWT(token);
            
            // 从载荷中获取用户名（手机号）
            String phone = claims.getSubject();
            log.info("Token解析成功，用户手机号: {}", phone);
            
            // 4. 根据手机号查询用户信息
            SysUser user = userMapper.findByPhone(phone);
            
            if (user != null) {
                // 用户存在，将用户信息存储到请求属性中
                // Controller中可通过 @CurrentUser 注解获取
                request.setAttribute("currentUser", user);
                
                log.info("用户验证成功，用户ID: {}", user.getUserId());
                
                // 5. 放行请求，继续执行Controller方法
                return true;
            } else {
                // 用户不存在（可能已被删除）
                log.warn("用户不存在，手机号: {}", phone);
                response.setStatus(401);  // 返回401未授权状态码
                return false;  // 拦截请求
            }
            
        } catch (Exception ex) {
            // Token无效、过期或解析失败
            log.error("JWT校验失败，原因: {}", ex.getMessage());
            
            // 6. 返回401未授权状态码
            response.setStatus(401);
            
            // 拦截请求，不执行Controller方法
            return false;
        }
    }
}